home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / SML⁄NJ 93+ / Documentation / examples / textbooks / four_lectures / interp4.sml < prev    next >
Encoding:
Text File  |  1995-12-30  |  14.9 KB  |  534 lines  |  [TEXT/R*ch]

  1. (* interp4.sml : adding identifiers and let 
  2.                  based on version 2 *)
  3.  
  4. signature INTERPRETER=
  5.    sig
  6.       val interpret: string -> string
  7.       val eval: bool ref
  8.       and tc  : bool ref
  9.    end;
  10.  
  11.                   (* syntax *)
  12.  
  13. signature EXPRESSION =
  14.    sig
  15.       datatype Expression =
  16.          SUMexpr of Expression * Expression   |
  17.          DIFFexpr of Expression * Expression   |
  18.          PRODexpr of Expression * Expression   |
  19.          BOOLexpr of bool   |
  20.          EQexpr of Expression * Expression   |
  21.          CONDexpr of Expression * Expression * Expression   |
  22.          CONSexpr of Expression * Expression   |
  23.          LISTexpr of Expression list   |
  24.          DECLexpr of string * Expression * Expression   |
  25.          RECDECLexpr of string * Expression * Expression   |
  26.          IDENTexpr of string   |
  27.          LAMBDAexpr of string * Expression   |
  28.          APPLexpr of Expression * Expression   |
  29.          NUMBERexpr of int
  30.    end
  31.  
  32.  
  33.               (* parsing *)
  34.  
  35. signature PARSER =
  36.    sig
  37.       structure E: EXPRESSION
  38.  
  39.       exception Lexical of string
  40.       exception Syntax of string
  41.  
  42.       val parse: string -> E.Expression
  43.    end
  44.  
  45.  
  46.                         (* environments *)
  47.  
  48. signature ENVIRONMENT =
  49.    sig
  50.       type 'object Environment
  51.  
  52.       exception Retrieve of string
  53.  
  54.       val emptyEnv: 'object Environment
  55.       val declare: string * 'object * 'object Environment -> 'object Environment
  56.       val retrieve: string * 'object Environment -> 'object
  57.    end
  58.  
  59.                         (* evaluation *)
  60. signature VALUE =
  61.    sig
  62.       type Value
  63.       exception Value
  64.  
  65.       val mkValueNumber: int -> Value
  66.           and unValueNumber: Value -> int
  67.  
  68.       val mkValueBool: bool -> Value
  69.           and unValueBool: Value -> bool
  70.  
  71.       val ValueNil: Value
  72.       val mkValueCons: Value * Value -> Value
  73.           and unValueHead: Value -> Value
  74.           and unValueTail: Value -> Value
  75.  
  76.       val eqValue: Value * Value -> bool
  77.       val printValue: Value -> string
  78.    end
  79.  
  80.  
  81. signature EVALUATOR =
  82.    sig
  83.       structure Exp: EXPRESSION
  84.       structure Val: VALUE
  85.       exception Unimplemented
  86.       val evaluate: Exp.Expression -> Val.Value
  87.    end
  88.  
  89.                   (* type checking *)
  90. signature TYPE =
  91.    sig
  92.       eqtype tyvar
  93.       val freshTyvar: unit -> tyvar
  94.       type Type 
  95.       type TypeScheme
  96.   
  97.       val instance: TypeScheme -> Type
  98.       val close: Type -> TypeScheme
  99.     (*constructors and decstructors*)
  100.       exception Type
  101.       val mkTypeInt: unit -> Type
  102.           and unTypeInt: Type -> unit
  103.  
  104.       val mkTypeBool: unit -> Type
  105.           and unTypeBool: Type -> unit
  106.  
  107.       val mkTypeList: Type -> Type
  108.           and unTypeList: Type -> Type
  109.  
  110.       val mkTypeTyvar: tyvar -> Type
  111.           and unTypeTyvar: Type -> tyvar
  112.  
  113.       type subst
  114.       val Id: subst                     (* the identify substitution;   *)
  115.       val mkSubst: tyvar*Type -> subst     (* make singleton substitution; *)
  116.       val on : subst * Type -> Type     (* application;                 *)
  117.  
  118.     
  119.       val prType: Type->string          (* printing *)
  120.    end
  121.  
  122.  
  123.  
  124. signature TYPECHECKER =
  125.    sig
  126.       structure Exp: EXPRESSION
  127.       structure Type: TYPE
  128.       exception NotImplemented of string
  129.       exception TypeError of Exp.Expression * string
  130.       val typecheck: Exp.Expression -> Type.Type
  131.    end;
  132.  
  133.                   (* the interpreter*)
  134.  
  135. functor Interpreter
  136.    (structure Ty: TYPE
  137.     structure Value : VALUE
  138.     structure Parser: PARSER
  139.     structure TyCh: TYPECHECKER
  140.     structure Evaluator:EVALUATOR
  141.       sharing Parser.E = TyCh.Exp = Evaluator.Exp
  142.           and TyCh.Type = Ty
  143.           and Evaluator.Val = Value
  144.    ): INTERPRETER=
  145.  
  146. struct
  147.   val eval= ref true    (* toggle for evaluation *)
  148.   and tc  = ref true    (* toggle for type checking *)
  149.   fun interpret(str)=
  150.     let val abstsyn= Parser.parse str
  151.         val typestr= if !tc then Ty.prType(TyCh.typecheck abstsyn)
  152.                      else "(disabled)"
  153.         val valuestr= if !eval then 
  154.                          Value.printValue(Evaluator.evaluate abstsyn)
  155.                       else "(disabled)"
  156.              
  157.     in  valuestr ^ " : " ^ typestr 
  158.     end
  159.     handle Evaluator.Unimplemented => "Evaluator not fully implemented"
  160.          | TyCh.NotImplemented msg => "Type Checker not fully implemented " ^ msg
  161.          | Value.Value   => "Run-time error"
  162.          | Parser.Syntax msg => "Syntax Error: " ^ msg
  163.          | Parser.Lexical msg=> "Lexical Error: " ^ msg
  164.          | TyCh.TypeError(_,msg)=> "Type Error: " ^ msg
  165. end;
  166.                
  167.                     (* the evaluator *)
  168.  
  169. functor Evaluator
  170.   (structure Expression: EXPRESSION
  171.    structure Value: VALUE):EVALUATOR=
  172.  
  173.    struct
  174.       structure Exp= Expression
  175.       structure Val= Value
  176.       exception Unimplemented
  177.  
  178.       local
  179.          open Expression Value
  180.          fun evaluate exp =
  181.             case exp
  182.               of BOOLexpr b => mkValueBool b
  183.                | NUMBERexpr i => mkValueNumber i
  184.                | SUMexpr(e1, e2) =>
  185.                     let val e1' = evaluate e1
  186.                         val e2' = evaluate e2
  187.                     in
  188.                        mkValueNumber(unValueNumber e1' + unValueNumber e2')
  189.                     end
  190.  
  191.                | DIFFexpr(e1, e2) =>
  192.                     let val e1' = evaluate e1
  193.                         val e2' = evaluate e2
  194.                     in
  195.                        mkValueNumber(unValueNumber e1' - unValueNumber e2')
  196.                     end
  197.  
  198.                | PRODexpr(e1, e2) =>
  199.                     let val e1' = evaluate e1
  200.                         val e2' = evaluate e2
  201.                     in
  202.                        mkValueNumber(unValueNumber e1' * unValueNumber e2')
  203.                     end
  204.  
  205.                | EQexpr _ => raise Unimplemented
  206.                | CONDexpr _ => raise Unimplemented
  207.                | CONSexpr _ => raise Unimplemented
  208.                | LISTexpr _ => raise Unimplemented
  209.                | DECLexpr _ => raise Unimplemented
  210.                | RECDECLexpr _ => raise Unimplemented
  211.                | IDENTexpr _ => raise Unimplemented
  212.                | LAMBDAexpr _ => raise Unimplemented
  213.                | APPLexpr _ => raise Unimplemented
  214.  
  215.       in
  216.          val evaluate = evaluate
  217.       end
  218.    end;
  219.  
  220.                         (* the type checker *)   
  221. signature UNIFY=
  222.    sig
  223.       structure Type: TYPE
  224.       exception NotImplemented of string
  225.       exception Unify
  226.       val unify: Type.Type * Type.Type -> Type.subst
  227.    end;
  228.  
  229. functor TypeChecker
  230.   (structure Ex: EXPRESSION
  231.    structure Ty: TYPE
  232.    structure Unify: UNIFY 
  233.       sharing Unify.Type = Ty
  234.    structure TE: ENVIRONMENT
  235.   )=
  236. struct
  237.   infix on 
  238.   val (op on) = Ty.on
  239.   structure Exp = Ex
  240.   structure Type = Ty
  241.   exception NotImplemented of string
  242.   exception TypeError of Ex.Expression * string
  243.  
  244.   fun tc (TE: Ty.TypeScheme TE.Environment, exp: Ex.Expression): Ty.Type =
  245.    (case exp of
  246.       Ex.BOOLexpr b => Ty.mkTypeBool()
  247.     | Ex.NUMBERexpr _ => Ty.mkTypeInt()
  248.     | Ex.SUMexpr(e1,e2)  => checkIntBin(TE,e1,e2)
  249.     | Ex.DIFFexpr(e1,e2) => checkIntBin(TE,e1,e2)
  250.     | Ex.PRODexpr(e1,e2) => checkIntBin(TE,e1,e2)
  251.     | Ex.LISTexpr [] =>
  252.          let val new = Ty.freshTyvar ()
  253.           in Ty.mkTypeList(Ty.mkTypeTyvar  new)
  254.          end
  255.     | Ex.LISTexpr(e::es) => tc (TE, Ex.CONSexpr(e,Ex.LISTexpr es))
  256.     | Ex.CONSexpr(e1,e2) =>
  257.         let val t1 = tc(TE, e1)
  258.             val t2 = tc(TE, e2)
  259.             val new = Ty.freshTyvar ()
  260.             val newt= Ty.mkTypeTyvar new
  261.             val t2' = Ty.mkTypeList newt
  262.             val S1 = Unify.unify(t2, t2')
  263.                      handle Unify.Unify=> 
  264.                      raise TypeError(e2,"expected list type")
  265.  
  266.             val S2 = Unify.unify(S1 on newt,S1 on t1)
  267.                      handle Unify.Unify=>
  268.                      raise TypeError(exp,"element and list have different types")
  269.          in S2 on (S1 on t2)
  270.         end
  271.     | Ex.EQexpr _ => raise NotImplemented "(equality)"
  272.     | Ex.CONDexpr _ => raise NotImplemented "(conditional)"
  273.     | Ex.DECLexpr(x,e1,e2) => 
  274.          let val t1 = tc(TE,e1);
  275.              val typeScheme = Ty.close(t1)
  276.           in tc(TE.declare(x,typeScheme,TE), e2)
  277.          end
  278.     | Ex.RECDECLexpr _ => raise NotImplemented "(rec decl)"
  279.     | Ex.IDENTexpr x   => 
  280.          (Ty.instance(TE.retrieve(x,TE))
  281.          handle TE.Retrieve _ => 
  282.           raise TypeError(exp,"identifier " ^ x ^ " not declared"))
  283.     | Ex.LAMBDAexpr _  => raise NotImplemented "(function)"
  284.     | Ex.APPLexpr _ => raise NotImplemented    "(application)"
  285.  
  286.    )handle Unify.NotImplemented msg => raise NotImplemented msg
  287.        
  288.   and checkIntBin(TE,e1,e2) =
  289.     let val t1 = tc(TE,e1)
  290.         val _  = Ty.unTypeInt t1
  291.                  handle Ty.Type=> raise TypeError(e1,"expected int")
  292.         val t2 = tc(TE,e2)
  293.         val _  = Ty.unTypeInt t2
  294.                  handle Ty.Type=> raise TypeError(e2,"expected int")
  295.      in Ty.mkTypeInt()
  296.     end;
  297.  
  298.   fun typecheck(e) = tc(TE.emptyEnv,e)
  299.  
  300. end; (*TypeChecker*)
  301.  
  302.  
  303.  
  304.  
  305.  
  306. functor Unify(Ty:TYPE):UNIFY=
  307. struct
  308.    structure Type = Ty
  309.    exception NotImplemented of string
  310.    exception Unify
  311.  
  312.    fun occurs(tv:Ty.tyvar,t:Ty.Type):bool=
  313.      (Ty.unTypeInt t; false)              handle Ty.Type=>
  314.      (Ty.unTypeBool t; false)             handle Ty.Type=>
  315.      let val tv' = Ty.unTypeTyvar t
  316.      in  tv=tv'
  317.      end                                  handle Ty.Type=>
  318.      let val t'  = Ty.unTypeList t
  319.      in  occurs(tv,t')
  320.      end                                  handle Ty.Type=>
  321.      raise NotImplemented "(the occur check)"
  322.  
  323.  
  324.    fun unify(t,t')=
  325.    let val tv = Ty.unTypeTyvar t
  326.     in let val tv' = Ty.unTypeTyvar t'
  327.         in Ty.mkSubst(tv,t')
  328.        end                                handle Ty.Type=>
  329.        if occurs(tv,t') then raise Unify
  330.        else Ty.mkSubst(tv,t')
  331.    end                                  handle Ty.Type=>
  332.    let val tv' = Ty.unTypeTyvar t'
  333.     in if occurs(tv',t) then raise Unify
  334.        else Ty.mkSubst(tv',t)
  335.    end                           handle Ty.Type=>
  336.    let val _ = Ty.unTypeInt t
  337.     in let val _ = Ty.unTypeInt t'
  338.         in Ty.Id
  339.        end handle Ty.Type=> raise Unify
  340.    end                    handle Ty.Type =>
  341.    let val _ = Ty.unTypeBool t
  342.     in let val _ = Ty.unTypeBool t'
  343.         in Ty.Id
  344.        end handle Ty.Type=> raise Unify
  345.    end                    handle Ty.Type=>
  346.    let val t = Ty.unTypeList t
  347.     in let val t' = Ty.unTypeList t'
  348.         in unify(t,t')
  349.        end handle Ty.Type => raise Unify
  350.    end                     handle Ty.Type=>
  351.    raise NotImplemented "(unify)"     
  352.  
  353. end; (*Unify*)
  354.   
  355.                      (* the basics -- nullary functors *)
  356.  
  357. functor Type():TYPE =
  358. struct
  359.   type tyvar = int
  360.   val freshTyvar =
  361.       let val r= ref 0 in fn()=>(r:= !r +1; !r) end
  362.   datatype Type = INT
  363.                 | BOOL
  364.                 | LIST of Type
  365.                 | TYVAR of tyvar  
  366.  
  367.   datatype TypeScheme = FORALL of tyvar list * Type
  368.  
  369.   fun instance(FORALL(tyvars,ty))=
  370.   let val old_to_new_tyvars = map (fn tv=>(tv,freshTyvar())) tyvars
  371.       exception Find;
  372.       fun find(tv,[])= raise Find
  373.       |   find(tv,(tv',new_tv)::rest)=
  374.           if tv=tv' then new_tv else find(tv,rest)
  375.       fun ty_instance INT = INT
  376.       |   ty_instance BOOL = BOOL
  377.       |   ty_instance (LIST t) = LIST(ty_instance t)
  378.       |   ty_instance (TYVAR tv) = 
  379.              TYVAR(find(tv,old_to_new_tyvars)
  380.                    handle Find=> tv)
  381.  
  382.   in 
  383.      ty_instance ty
  384.   end
  385.              
  386.   fun close(ty)=
  387.   let fun fv(INT) = []
  388.       |   fv(BOOL)= []
  389.       |   fv(LIST t) = fv(t)
  390.       |   fv(TYVAR tv) = [tv]
  391.    in FORALL(fv ty,ty)
  392.   end;
  393.  
  394.   exception Type
  395.  
  396.   fun mkTypeInt() = INT
  397.   and unTypeInt(INT)=()
  398.     | unTypeInt(_)= raise Type
  399.  
  400.   fun mkTypeBool() = BOOL
  401.   and unTypeBool(BOOL)=()
  402.     | unTypeBool(_)= raise Type
  403.  
  404.   fun mkTypeList(t)=LIST t
  405.   and unTypeList(LIST t)= t
  406.     | unTypeList(_)= raise Type
  407.  
  408.   fun mkTypeTyvar tv = TYVAR tv
  409.   and unTypeTyvar(TYVAR tv) = tv
  410.     | unTypeTyvar _ = raise Type
  411.   
  412.   type subst = Type -> Type
  413.  
  414.   fun Id x = x
  415.   fun mkSubst(tv,ty)=
  416.      let fun su(TYVAR tv')= if tv=tv' then ty else TYVAR tv'
  417.          |   su(INT) = INT
  418.          |   su(BOOL)= BOOL
  419.          |   su(LIST ty') = LIST (su ty')
  420.       in su
  421.      end
  422.  
  423.  
  424.   fun on(S,t)= S(t)
  425.  
  426.   fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  427.   and natToString(n:int)=
  428.       let val d = n div 10 in
  429.         if d = 0 then chr(ord"0" + n)
  430.         else natToString(d)^ chr(ord"0" + (n mod 10))
  431.       end
  432.  
  433.   fun prType INT = "int"
  434.   |   prType BOOL= "bool"
  435.   |   prType (LIST ty) = "(" ^ prType ty ^ ")list"
  436.   |   prType (TYVAR tv) = "a" ^ intToString tv
  437. end;
  438.  
  439.  
  440.  
  441. functor Environment() =
  442. struct
  443.    type 'a Environment = (string *  'a )list
  444.  
  445.    exception Retrieve of string;
  446.    
  447.    val emptyEnv = [];
  448.  
  449.    fun declare(s:string,obj:'a,e:'a Environment)=
  450.        (s,obj)::e
  451.  
  452.    fun retrieve(s,[])= raise Retrieve(s)
  453.    |   retrieve(s,(s',obj)::rest) =
  454.            if s=s' then obj else retrieve(s,rest)
  455.  
  456. end;
  457.  
  458. functor Expression(): EXPRESSION =
  459.    struct
  460.       type 'a pair = 'a * 'a
  461.  
  462.       datatype Expression =
  463.          SUMexpr of Expression pair   |
  464.          DIFFexpr of Expression pair   |
  465.          PRODexpr of Expression pair   |
  466.          BOOLexpr of bool   |
  467.          EQexpr of Expression pair   |
  468.          CONDexpr of Expression * Expression * Expression   |
  469.          CONSexpr of Expression pair   |
  470.          LISTexpr of Expression list   |
  471.          DECLexpr of string * Expression * Expression   |
  472.          RECDECLexpr of string * Expression * Expression   |
  473.          IDENTexpr of string   |
  474.          LAMBDAexpr of string * Expression   |
  475.          APPLexpr of Expression * Expression   |
  476.          NUMBERexpr of int
  477.    end;
  478.  
  479. functor Value(): VALUE =
  480.    struct
  481.       type 'a pair = 'a * 'a
  482.  
  483.       datatype Value = NUMBERvalue of int   |
  484.                       BOOLvalue of bool   |
  485.                       NILvalue   |
  486.                       CONSvalue of Value pair
  487.  
  488.       exception Value
  489.  
  490.       val mkValueNumber = NUMBERvalue
  491.       val mkValueBool = BOOLvalue
  492.  
  493.       val ValueNil = NILvalue
  494.       val mkValueCons = CONSvalue
  495.  
  496.       fun unValueNumber(NUMBERvalue(i)) = i   |
  497.           unValueNumber(_) = raise Value
  498.  
  499.       fun unValueBool(BOOLvalue(b)) = b   |
  500.           unValueBool(_) = raise Value
  501.  
  502.       fun unValueHead(CONSvalue(c, _)) = c   |
  503.           unValueHead(_) = raise Value
  504.  
  505.       fun unValueTail(CONSvalue(_, c)) = c   |
  506.           unValueTail(_) = raise Value
  507.  
  508.       fun eqValue(c1, c2) = (c1 = c2)
  509.  
  510.                 (* Pretty-printing *)
  511.       fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  512.       and natToString(n:int)=
  513.           let val d = n div 10 in
  514.             if d = 0 then chr(ord"0" + n)
  515.             else natToString(d)^ chr(ord"0" + (n mod 10))
  516.           end
  517.       fun printValue(NUMBERvalue(i)) = intToString(i)   |
  518.           printValue(BOOLvalue(true)) = "true"   |
  519.           printValue(BOOLvalue(false)) = "false"   |
  520.           printValue(NILvalue) = "[]"   |
  521.           printValue(CONSvalue(cons)) = "[" ^ printValueList(cons) ^ "]"
  522.           and printValueList(hd, NILvalue) = printValue(hd)   |
  523.               printValueList(hd, CONSvalue(tl)) =
  524.                  printValue(hd) ^ ", " ^ printValueList(tl)   |
  525.               printValueList(_) = raise Value
  526.    end;
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.